﻿using ICSharpCode.SharpZipLib.GZip;
using ICSharpCode.SharpZipLib.Zip.Compression.Streams;
using Newtonsoft.Json.Linq;
using System.Xml;

namespace up6.utils;

public class UtilsTool
{

    public static Dictionary<string, bool> toDic(string[] arr)
    {
        Dictionary<string, bool> dic = new Dictionary<string, bool>();
        foreach (var a in arr)
        {
            dic.Add(a, true);
        }
        return dic;
    }

    public static string merge(JToken t, string field = "name", string tmp = "{0}", string separator = ",")
    {
        List<string> list = new List<string>();
        foreach (JToken o in t)
        {
            list.Add(string.Format(tmp, o[field].ToString().Trim()));
        }
        return string.Join(separator, list);
    }

    public static string merge(string[] arr, string tmp = "{0}", string separator = ",")
    {
        List<string> list = new List<string>();
        foreach (var o in arr)
        {
            list.Add(string.Format(tmp, o.Trim()));
        }
        return string.Join(separator, list);
    }

    /// <summary>
    /// 将int数值转换为占四个字节的byte数组，本方法适用于(低位在前，高位在后)的顺序。 和bytesToInt（）配套使用
    /// </summary>
    /// <param name="value"></param>
    /// <returns></returns>
    public static byte[] intToBytes(int value)
    {
        byte[] src = new byte[4];
        src[3] = (byte)((value >> 24) & 0xFF);
        src[2] = (byte)((value >> 16) & 0xFF);
        src[1] = (byte)((value >> 8) & 0xFF);
        src[0] = (byte)(value & 0xFF);
        return src;
    }

    /// <summary>
    /// 将int数值转换为占四个字节的byte数组，本方法适用于(高位在前，低位在后)的顺序。  和bytesToInt2（）配套使用
    /// </summary>
    /// <param name="value"></param>
    /// <returns></returns>
    public static byte[] intToBytes2(int value)
    {
        byte[] src = new byte[4];
        src[0] = (byte)((value >> 24) & 0xFF);
        src[1] = (byte)((value >> 16) & 0xFF);
        src[2] = (byte)((value >> 8) & 0xFF);
        src[3] = (byte)(value & 0xFF);
        return src;
    }

    /// <summary>
    /// byte数组中取int数值，本方法适用于(低位在前，高位在后)的顺序，和和intToBytes（）配套使用
    /// </summary>
    /// <param name="src"></param>
    /// <param name="offset"></param>
    /// <returns></returns>
    public static int bytesToInt(byte[] src, int offset = 0)
    {
        int value;
        value = (int)((src[offset] & 0xFF)
                | ((src[offset + 1] & 0xFF) << 8)
                | ((src[offset + 2] & 0xFF) << 16)
                | ((src[offset + 3] & 0xFF) << 24));
        return value;
    }

    /// <summary>
    /// byte数组中取int数值，本方法适用于(低位在后，高位在前)的顺序。和intToBytes2（）配套使用
    /// </summary>
    /// <param name="src"></param>
    /// <param name="offset"></param>
    /// <returns></returns>
    public static int bytesToInt2(byte[] src, int offset = 0)
    {
        int value;
        value = (int)(((src[offset] & 0xFF) << 24)
                | ((src[offset + 1] & 0xFF) << 16)
                | ((src[offset + 2] & 0xFF) << 8)
                | (src[offset + 3] & 0xFF));
        return value;
    }

    public static string xmlToString(ref XmlDocument doc)
    {
        MemoryStream stream = new MemoryStream();
        XmlTextWriter writer = new XmlTextWriter(stream, System.Text.Encoding.UTF8);
        writer.Formatting = Formatting.Indented;
        doc.Save(writer);

        StreamReader sr = new StreamReader(stream, System.Text.Encoding.UTF8);
        stream.Position = 0;
        string str = sr.ReadToEnd();
        sr.Close();
        return str;
    }

    public static byte[] toBytes(Stream s)
    {
        byte[] arr = new byte[s.Length];
        s.Read(arr, 0, arr.Length);
        return arr;
    }

    /// <summary>
    /// sm4-cbc-pkcs7padding-块对齐大小
    /// </summary>
    public static int sm4AlignBlockSize(int blockSize)
    {
        int len = blockSize % 16;
        len = 16 - len;
        return blockSize + len;
    }

    public static Stream unCompress(Stream s, string tp)
    {
        if (tp == "zip") return unZip(s);
        return unGzip(s);
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="s"></param>
    /// <param name="type">gzip,zip</param>
    /// <returns></returns>
    public static Stream unGzip(Stream s)
    {
        s.Seek(0, SeekOrigin.Begin);
        var gz = new GZipInputStream(s);
        var ms = new MemoryStream();
        gz.CopyTo(ms);
        return ms;
    }

    public static Stream unZip(Stream s)
    {
        s.Seek(0, SeekOrigin.Begin);
        var z = new InflaterInputStream(s);
        var ms = new MemoryStream();
        z.CopyTo(ms);
        return ms;
    }
}